package com.example.antdback.controller;

import com.alibaba.nacos.common.utils.ThreadUtils;
import com.example.antdback.entity.User;
import com.example.antdback.entity.model.Result;
import com.example.antdback.service.UserService;
import com.example.antdback.utils.RedisLockerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author ljg
 * description
 * @since 2021/8/29 12:25 下午
 **/
@Slf4j
@RefreshScope
@CacheConfig(cacheNames = "user")
@RestController
@RequestMapping("test")
public class TestController {

    @Resource
    private UserService userService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private RedisLockerUtil redisLockerUtil;
    @Value("${message}")
    private String message;

    @GetMapping("hello")
    public Result<Void> getHello() {
        return Result.SUCCESS;
    }

    /**
     * 查询用户地址，并缓存到demo缓存空间上
     * 这里设置value会覆盖类上的cacheNames
     **/
    @Cacheable(key = "'myTestController_'+#status")
    @GetMapping("userRedis")
    public Result<List<String>> redis(String status){
        List<String> collect = userService.lambdaQuery().eq(User::getStatus, status).list()
                .stream().map(User::getAddress).collect(Collectors.toList());
        return Result.success(collect);
    }

    /**
     * 删除demo缓存空间上的所有缓存，
     * 只会删除指定的value（命名空间）的全部缓存，比如这里只会删除value=user的，其他不会删
     * 这里设置value会覆盖类上的cacheNames
     **/
    @GetMapping("deleteRedis")
    @CacheEvict(allEntries = true)
    public Result<Void> deleteRedis() {
        return Result.SUCCESS;
    }

    /**
     * 单独使用redisTemplate来操作缓存
     **/
    @GetMapping("redisTest")
    public Result<Void> redisTest() {
        User v = new User();
        v.setAddress("昆明市五华区");
        v.setName("张建");
        redisTemplate.opsForValue().set("test::user001", v);
        return Result.SUCCESS;
    }

    @GetMapping("getNaocsMsg")
    public Result<String> getNaocsMsg() {
        log.info("message==" + message);
        return Result.success(message);
    }

    /**
     * @author ljg
     * 支付测试
     * @param code 编码
     * @since 2021/9/3 8:42 下午
     **/
    @GetMapping("payTest")
    public Result<String> payTest(@RequestParam String code) {
        String lockKey = String.format("pay_test_%s", code);
        log.info("请求进来了----");
        boolean tryLock = redisLockerUtil.tryLock(lockKey, TimeUnit.SECONDS, 1, 20);
        log.info("tryLock==" + tryLock);
        if(!tryLock) {
            return Result.fail(code + "正在支付中");
        }
        try {
            log.info("开始支付");
            ThreadUtils.sleep(10000);
            log.info("支付完成");
        } finally {
            redisLockerUtil.unlock(lockKey);
        }
        return Result.success("成功");
    }

}
